home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume9 / xterm / part07 < prev    next >
Encoding:
Internet Message Format  |  1987-04-21  |  60.4 KB

  1. Subject:  v09i060:  Terminal emulator for X window system, Part07/07
  2. Newsgroups: mod.sources, comp.sources.unix
  3. Approved: rs@mirror.TMC.COM
  4.  
  5. Submitted by: edmoy@opal.Berkeley.EDU
  6. Mod.sources: Volume 9, Issue 60
  7. Archive-name: xterm6.6b/Part07
  8.  
  9. [  Following the schedule, I'll be posting articles to both the old and
  10.    the new name for a while; sorry, notes sites.  --r$  ]
  11.   
  12.  
  13. #! /bin/sh
  14. # This is a shell archive, meaning:
  15. # 1. Remove everything above the #! /bin/sh line.
  16. # 2. Save the resulting text in a file.
  17. # 3. Execute the file with /bin/sh (not csh) to create the files:
  18. #    Makefile scrollbar.c tabs.c termcap terminfo util.c Xlib/Makefile
  19. #    Xlib/README Xlib/XKeyBind.c
  20. if test -f Makefile
  21. then
  22.     echo shar: will not overwrite existing file "'Makefile'"
  23. else
  24. echo 'x - Makefile'
  25. cat << \RAZZLE!DAZZLE > Makefile
  26. #
  27. #     $Source: /u1/X/xterm/RCS/Makefile,v $
  28. #    $Header: Makefile,v 10.2 86/12/01 17:52:22 swick Rel $
  29. #
  30.  
  31. #
  32. #    Makefile for X window system terminal emulator.
  33. #    @(#)Makefile       X10/6.6B 12/26/86
  34. #
  35.  
  36. DESTDIR=
  37. # We put xterm in /etc so you can run on partial boot.  A link is put
  38. # in CONFDIR so normal search paths will find xterm.
  39. # For the 4.3 distribution, the executable is put in /usr/local instead.
  40. #
  41. CONFDIR= /usr/local
  42. INCLUDES= -I../include
  43. LIBS= ../Xlib/libX.a -ltermcap
  44. #
  45. # The option KEYBD may be included if the keyboard mods have been done to
  46. # XKeyBind.c in libX.a.
  47. cflags = -O -DMODEMENU ${INCLUDES} -DUTMP -DKEYBD
  48. #
  49. # NOWINDOWMENU    disables the window manager menu (right button)
  50. # DROPMENUS    causes the menus to drop from the cursor rather than be
  51. #        centered vertically.
  52. #cflags = -O -DMODEMENU ${INCLUDES} -DUTMP -DNOWINDOWMENU -DDROPMENUS
  53. CFLAGS = -R ${cflags}
  54. SOURCE = Makefile data.h error.h menu.h ptyx.h scrollbar.h VTparse.h \
  55.         Tekparse.h button.c charproc.c cursor.c data.c input.c \
  56.         main.c menu.c misc.c screen.c scrollbar.c tabs.c \
  57.         Tekparsetable.c Tekproc.c util.c VTparsetable.c
  58.  
  59. .SUFFIXES: .o .h .c
  60.  
  61. OBJS =    main.o input.o charproc.o cursor.o util.o tabs.o \
  62.     screen.o scrollbar.o button.o Tekproc.o misc.o \
  63.     VTparsetable.o Tekparsetable.o data.o menu.o
  64.  
  65. all: xterm resize
  66.  
  67. xterm: $(OBJS) ../Xlib/libX.a
  68.     $(CC) $(CFLAGS) -o xterm $(OBJS) $(LIBS)
  69.  
  70. button.o: data.h error.h menu.h ptyx.h scrollbar.h
  71.  
  72. charproc.o: VTparse.h error.h data.h menu.h ptyx.h scrollbar.h
  73.  
  74. cursor.o: ptyx.h
  75.  
  76. data.o: data.c ptyx.h scrollbar.h
  77.     $(CC) $(cflags) -c data.c
  78.  
  79. input.o: ptyx.h
  80.  
  81. main.o: data.h error.h main.h ptyx.h scrollbar.h
  82.  
  83. menu.o: menu.h
  84.  
  85. misc.o: error.h ptyx.h scrollbar.h gray.ic hilite.ic icon.ic wait.ic waitmask.ic
  86.  
  87. screen.o: error.h ptyx.h scrollbar.h
  88.  
  89. scrollbar.o: error.h ptyx.h scrollbar.h button.ic dark.ic light.ic upline.ic \
  90.     downline.ic uppage.ic downpage.ic top.ic bottom.ic saveoff.ic saveon.ic
  91.  
  92. tabs.o: ptyx.h
  93.  
  94. Tekparsetable.o: Tekparse.h
  95.  
  96. Tekproc.o: Tekparse.h error.h data.h menu.h ptyx.h scrollbar.h
  97.  
  98. VTparsetable.o: VTparse.h
  99.  
  100. util.o: ptyx.h scrollbar.h
  101.  
  102. resize: resize.o
  103.     $(CC) $(cflags) -o resize resize.o -lc -ltermcap
  104.  
  105. resize.o: resize.c
  106.     $(CC) $(cflags) -c resize.c
  107.  
  108. install: all
  109. #    install -m 4755 xterm ${DESTDIR}/etc
  110.     install -m 4755 xterm ${DESTDIR}${CONFDIR}
  111. #    rm -f ${DESTDIR}${CONFDIR}/xterm
  112. #    ln -s /etc/xterm ${DESTDIR}${CONFDIR}/xterm
  113.     install resize ${DESTDIR}${CONFDIR}
  114.  
  115. clean:
  116.     rm -f xterm resize *.o a.out core errs gmon.out *.bak *~
  117.  
  118. print:
  119.     lpr -Pln ${SOURCE}
  120. RAZZLE!DAZZLE
  121. fi    # End Makefile
  122. if test -f scrollbar.c
  123. then
  124.     echo shar: will not overwrite existing file "'scrollbar.c'"
  125. else
  126. echo 'x - scrollbar.c'
  127. cat << \RAZZLE!DAZZLE > scrollbar.c
  128. /*
  129.  *    $Source: /u1/X/xterm/RCS/scrollbar.c,v $
  130.  *    $Header: scrollbar.c,v 10.100 86/12/01 14:45:27 jg Rel $
  131.  */
  132.  
  133. #include <stdio.h>
  134. #include <sys/time.h>
  135. #include <X/Xlib.h>
  136. #include <setjmp.h>
  137. #include "scrollbar.h"
  138. #include "ptyx.h"
  139. #include "data.h"
  140. #include "error.h"
  141. #ifdef MODEMENU
  142. #include "menu.h"
  143. #endif MODEMENU
  144.  
  145. #include "button.ic"
  146. #include "dark.ic"
  147. #include "light.ic"
  148. #include "upline.ic"
  149. #include "downline.ic"
  150. #include "uppage.ic"
  151. #include "downpage.ic"
  152. #include "top.ic"
  153. #include "bottom.ic"
  154. #include "saveoff.ic"
  155. #include "saveon.ic"
  156. #ifndef lint
  157. static char sccs_id[] = "@(#)scrollbar.c\tX10/6.6B\t12/26/86";
  158. #endif    lint
  159.  
  160. static struct timeval stepspeed;
  161.  
  162. ScrollBar *
  163. CreateScrollBar(w, x, y, height, fg, bg, bordertile, val, valregion,
  164.  topval, botval, arrow)
  165.     Window w;
  166.     int x, y, height, fg, bg, val, valregion, topval, botval;
  167.     Pixmap bordertile;
  168.     Cursor arrow;
  169. {
  170.     register ScrollBar *sb;
  171.     register int i;
  172.     Pixmap btile, bgnd;
  173.     extern char *calloc();
  174.     static Window Make_tiled_window();
  175.     extern Pixmap Make_tile();
  176.  
  177.     if(!w || height < MINSCROLLBARHEIGHT ||
  178.      (sb = (ScrollBar *)calloc(1, sizeof(ScrollBar))) == NULL)
  179.         return(NULL);
  180.     btile = bordertile;
  181.     if(bg == BlackPixel && fg == WhitePixel) {
  182.         bg = WhitePixel;
  183.         fg = BlackPixel;
  184.         if(btile == WhitePixmap)
  185.             btile = BlackPixmap;
  186.     }
  187.     sb->fg = fg;
  188.     sb->bg = bg;
  189.     sb->cursor = arrow;
  190.     if((sb->bar = Make_tiled_window(light_width, light_height, light_bits,
  191.      fg, bg, &bgnd, w, x, y, (SCROLLBARWIDTH - 1), height, 1, bordertile))
  192.      == NULL)
  193.         goto failed_bar;
  194.     if((sb->button = XCreateWindow(sb->bar, -1, -1, (SCROLLBARWIDTH - 1),
  195.      BUTTONHEIGHT - 1, 1, btile, bgnd)) == NULL)
  196.         goto failed_button;
  197.     if((sb->save = XCreateWindow(sb->bar, -1, BUTTONHEIGHT - 1,
  198.      (SCROLLBARWIDTH - 1), BUTTONHEIGHT - 1, 1, btile, bgnd)) == NULL)
  199.         goto failed_save;
  200.     if((sb->region = Make_tiled_window(dark_width, dark_height, dark_bits,
  201.      fg, bg, &bgnd, sb->bar, 0, 0, (SCROLLBARWIDTH - 1), 10, 0,
  202.      (Pixmap)NULL)) == NULL) {
  203.         XDestroyWindow(sb->save);
  204. failed_save:
  205.         XDestroyWindow(sb->button);
  206. failed_button:
  207.         XDestroyWindow(sb->bar);
  208. failed_bar:
  209.         free((char *)sb);
  210.         return(NULL);
  211.     }
  212.     sb->savebits[SAVE_OFF] = saveoff_bits;
  213.     sb->savebits[SAVE_ON] = saveon_bits;
  214.     sb->buttonbits[BUTTON_UPLINE / 2] = upline_bits;
  215.     sb->buttonbits[BUTTON_DOWNLINE / 2] = downline_bits;
  216.     sb->buttonbits[BUTTON_UPPAGE / 2] = uppage_bits;
  217.     sb->buttonbits[BUTTON_DOWNPAGE / 2] = downpage_bits;
  218.     sb->buttonbits[BUTTON_TOP / 2] = top_bits;
  219.     sb->buttonbits[BUTTON_BOTTOM / 2] = bottom_bits;
  220.     sb->buttonbits[BUTTON_NORMAL / 2] = button_bits;
  221.     XDefineCursor(sb->bar, sb->cursor);
  222.     XSelectInput(sb->bar, ButtonPressed | ButtonReleased | ExposeWindow |
  223.      EnterWindow | LeaveWindow | UnmapWindow);
  224.     XSelectInput(sb->button, EnterWindow | LeaveWindow);
  225.     XMapWindow(sb->button);    /* will really map when bar is mapped */
  226.     XMapWindow(sb->save);    /* will really map when bar is mapped */
  227.     sb->buttonstate = sb->buttonset = BUTTON_NORMAL;
  228.     sb->savestate = sb->saveset = SAVE_ON;
  229.     sb->set.value = val;
  230.     sb->set.regionheight = valregion;
  231.     sb->set.topvalue = topval;
  232.     sb->set.bottomvalue = botval;
  233.     sb->set.height = height - BARSTART;
  234.     return(sb);
  235. }
  236.  
  237. ShowScrollBar(sb)
  238.     register ScrollBar *sb;
  239. {
  240.     if(sb->visible)
  241.         return;
  242.     sb->visible = 1;
  243.     if(sb->regionvisible) {
  244.         XUnmapWindow(sb->region);
  245.         sb->regionvisible = 0;
  246.     }
  247.     XMapWindow(sb->bar);
  248.     DrawScrollRegion(sb);
  249.     sb->action = SHOW;
  250. }
  251.  
  252. HideScrollBar(sb)
  253.     register ScrollBar *sb;
  254. {
  255.     if(!sb->visible)
  256.         return;
  257.     sb->visible = 0;
  258.     XUnmapWindow(sb->bar);
  259. }
  260.  
  261. DrawScrollRegion(sb)
  262.     register ScrollBar *sb;
  263. {
  264.     register int region, temp;
  265.  
  266.     if(sb->set.regionheight <= 0)
  267.         sb->set.regionheight = 0;
  268.     if((region = sb->set.topvalue - sb->set.bottomvalue) >= 0) {
  269.         if(sb->set.value > sb->set.topvalue)
  270.             sb->set.value = sb->set.topvalue;
  271.         else if(sb->set.value < sb->set.bottomvalue)
  272.             sb->set.value = sb->set.bottomvalue;
  273.     } else {
  274.         region = -region;
  275.         if(sb->set.value < sb->set.topvalue)
  276.             sb->set.value = sb->set.topvalue;
  277.         else if(sb->set.value > sb->set.bottomvalue)
  278.             sb->set.value = sb->set.bottomvalue;
  279.     }
  280.     if(sb->set.value == sb->set.topvalue) {
  281.         sb->set.pixelheight = (region == 0) ? sb->set.height :
  282.          (sb->set.height - 1) * sb->set.regionheight /
  283.          (sb->set.regionheight + region);
  284.         sb->set.y = BARSTART;
  285.     } else if(sb->set.value == sb->set.bottomvalue) {
  286.         sb->set.pixelheight = (sb->set.height - 1) *
  287.          sb->set.regionheight / (sb->set.regionheight + region);
  288.         sb->set.y = BARSTART + sb->set.height - sb->set.pixelheight;
  289.     } else {
  290.         if(sb->set.topvalue >= sb->set.bottomvalue) {
  291.             temp = sb->set.topvalue - 1;
  292.             region = temp - (sb->set.bottomvalue + 1);
  293.             sb->set.y = temp - sb->set.value;
  294.         } else {
  295.             temp = sb->set.topvalue + 1;
  296.             region = (sb->set.bottomvalue - 1) - temp;
  297.             sb->set.y = sb->set.value - temp;
  298.         }
  299.         sb->set.y = (BARSTART + 1) + sb->set.y * (sb->set.height - 2) /
  300.          (temp = sb->set.regionheight + region);
  301.         sb->set.pixelheight = (sb->set.height - 2) *
  302.          sb->set.regionheight / temp;
  303.     }
  304.     if(sb->set.pixelheight <= 0)
  305.         sb->set.pixelheight = 1;
  306.     if(sb->set.regionheight == 0) {
  307.         sb->state = sb->set;
  308.         if(sb->regionvisible) {
  309.             XUnmapWindow(sb->region);
  310.             sb->regionvisible = 0;
  311.         }
  312.         return;
  313.     }
  314.     if(!sb->visible || sb->regionvisible
  315.      && sb->state.y == sb->set.y
  316.      && sb->state.pixelheight == sb->set.pixelheight) {
  317.         sb->state = sb->set;
  318.         return;
  319.     }
  320.     sb->state = sb->set;
  321.     XConfigureWindow(sb->region, 0, sb->state.y, (SCROLLBARWIDTH - 1),
  322.      sb->state.pixelheight);
  323.     if(!sb->regionvisible) {
  324.         XMapWindow(sb->region);
  325.         sb->regionvisible = 1;
  326.     }
  327. }
  328.  
  329. DrawButton(sb)
  330.     register ScrollBar *sb;
  331. {
  332.     register int fg, bg;
  333.  
  334.     if(sb->visible && sb->buttonstate != sb->buttonset) {
  335.         if((sb->buttonstate = sb->buttonset) & HILITED) {
  336.             fg = sb->bg;
  337.             bg = sb->fg;
  338.         } else {
  339.             fg = sb->fg;
  340.             bg = sb->bg;
  341.         }
  342.         XBitmapBitsPut(sb->button, 0, 0, SCROLLBARWIDTH - 1,
  343.          BUTTONHEIGHT - 1, sb->buttonbits[sb->buttonstate / 2],
  344.          fg, bg, (Bitmap)0, GXcopy, AllPlanes);
  345.     }
  346. }
  347.  
  348. DrawSave(sb)
  349.     register ScrollBar *sb;
  350. {
  351.     if(sb->visible && sb->savestate != sb->saveset)
  352.         XBitmapBitsPut(sb->save, 0, 0, SCROLLBARWIDTH - 1,
  353.          BUTTONHEIGHT - 1, sb->savebits[sb->savestate = sb->saveset],
  354.          sb->fg, sb->bg, (Bitmap)0, GXcopy, AllPlanes);
  355. }
  356.  
  357. ResizeScrollBar(sb, x, y, height, region)
  358.     register ScrollBar *sb;
  359.     int x, y, height, region;
  360. {
  361.     register int act;
  362.  
  363.     act = sb->action;
  364.     sb->action = NONE;
  365.     switch(act) {
  366.      case SHOW:
  367.         return;
  368.      case HIDE:
  369.         HideScrollBar(sb);
  370.         return;
  371.     }
  372.     if(!sb->visible)
  373.         return;
  374.     if(sb->regionvisible) {
  375.         XUnmapWindow(sb->region);
  376.         sb->regionvisible = 0;
  377.     }
  378.     XConfigureWindow(sb->bar, x, y, (SCROLLBARWIDTH - 1), height);
  379.     sb->set.height = height - BARSTART;
  380.     sb->set.regionheight = region;
  381.     DrawScrollRegion(sb);
  382. }
  383.  
  384. PositionRegion(sb, y)
  385.     register ScrollBar *sb;
  386.     register int y;
  387. {
  388.     if(y <= BARSTART)
  389.         sb->set.value = sb->set.topvalue;
  390.     else if(y >= BARSTART + sb->set.height *
  391.      (sb->set.bottomvalue - sb->set.topvalue) /
  392.      (sb->set.bottomvalue + sb->set.regionheight - sb->set.topvalue))
  393.         sb->set.value = sb->set.bottomvalue;
  394.     else
  395.         sb->set.value = sb->set.topvalue + (y - BARSTART) *
  396.          (sb->set.bottomvalue + sb->set.regionheight - sb->set.topvalue)
  397.          / sb->set.height;
  398.     DrawScrollRegion(sb);
  399.     return(sb->state.value);
  400. }
  401.  
  402. ButtonRegion(sb)
  403.     register ScrollBar *sb;
  404. {
  405.     register int reverse, pagesize;
  406.  
  407.     if(!(sb->buttonset & HILITED))
  408.         return(sb->set.value);
  409.     reverse = (sb->set.bottomvalue > sb->set.topvalue);
  410.     pagesize = sb->set.regionheight - 1;
  411.     switch(sb->buttonset) {
  412.      case BUTTON_UPLINEHI:
  413.         if(reverse)
  414.             sb->set.value--;
  415.         else
  416.             sb->set.value++;
  417.         break;
  418.      case BUTTON_DOWNLINEHI:
  419.         if(reverse)
  420.             sb->set.value++;
  421.         else
  422.             sb->set.value--;
  423.         break;
  424.      case BUTTON_UPPAGEHI:
  425.         if(reverse)
  426.             sb->set.value -= pagesize;
  427.         else
  428.             sb->set.value += pagesize;
  429.         break;
  430.      case BUTTON_DOWNPAGEHI:
  431.         if(reverse)
  432.             sb->set.value += pagesize;
  433.         else
  434.             sb->set.value -= pagesize;
  435.         break;
  436.      case BUTTON_TOPHI:
  437.         sb->set.value = sb->set.topvalue;
  438.         break;
  439.      case BUTTON_BOTTOMHI:
  440.         sb->set.value = sb->set.bottomvalue;
  441.     }
  442.     DrawScrollRegion(sb);
  443.     return(sb->set.value);
  444. }
  445.  
  446. DownButtonDown(term, reply, pty)
  447.     Terminal *term;
  448.     register XKeyOrButtonEvent *reply;
  449.     int pty;            /* file descriptor of pty */
  450. {
  451.     register Screen *screen = &term->screen;
  452.     register ScrollBar *sb = screen->sb;
  453.     register Window window = reply->subwindow;
  454.  
  455.     if(!window || window == sb->region) {
  456.         WindowScroll(screen, PositionRegion(sb, reply->y));
  457.         return;
  458.     }
  459.     if(window == sb->save) {
  460.         SetSaveState(sb, !GetSaveState(sb));
  461.         return;
  462.     }
  463.     if(window != sb->button || !XGrabMouse(sb->button, sb->cursor,
  464.      ButtonReleased | EnterWindow | LeaveWindow)) {
  465.         Bell();
  466.         return;
  467.     }
  468.     if(reply->detail & ControlMask)
  469.         sb->buttonset = BUTTON_BOTTOMHI;
  470.     else if(reply->detail & ShiftMask)
  471.         sb->buttonset = BUTTON_DOWNPAGEHI;
  472.     else {
  473.         sb->buttonset = BUTTON_DOWNLINEHI;
  474.         stepspeed.tv_usec = PAUSETIME;
  475.         screen->timeout = &stepspeed;
  476.         WindowScroll(screen, ButtonRegion(screen->sb));
  477.     }
  478.     DrawButton(sb);
  479. }
  480.  
  481. UpButtonDown(term, reply, pty)
  482.     Terminal *term;
  483.     register XKeyOrButtonEvent *reply;
  484.     int pty;            /* file descriptor of pty */
  485. {
  486.     register Screen *screen = &term->screen;
  487.     register ScrollBar *sb = screen->sb;
  488.     register Window window = reply->subwindow;
  489.  
  490.     if(!window || window == sb->region) {
  491.         WindowScroll(screen, PositionRegion(sb, reply->y));
  492.         return;
  493.     }
  494.     if(window == sb->save) {
  495.         SetSaveState(sb, !GetSaveState(sb));
  496.         return;
  497.     }
  498.     if(window != sb->button || !XGrabMouse(sb->button, sb->cursor,
  499.      ButtonReleased | EnterWindow | LeaveWindow)) {
  500.         Bell();
  501.         return;
  502.     }
  503.     if(reply->detail & ControlMask)
  504.         sb->buttonset = BUTTON_TOPHI;
  505.     else if(reply->detail & ShiftMask)
  506.         sb->buttonset = BUTTON_UPPAGEHI;
  507.     else {
  508.         sb->buttonset = BUTTON_UPLINEHI;
  509.         stepspeed.tv_usec = PAUSETIME;
  510.         screen->timeout = &stepspeed;
  511.         WindowScroll(screen, ButtonRegion(screen->sb));
  512.     }
  513.     DrawButton(sb);
  514. }
  515.  
  516. ButtonUp(term, reply, pty)
  517.     Terminal *term;
  518.     XKeyOrButtonEvent *reply;
  519.     int pty;            /* file descriptor of pty */
  520. {
  521.     register Screen *screen = &term->screen;
  522.     register ScrollBar *sb = screen->sb;
  523.     register int state;
  524.  
  525.     if((state = GetButtonState(sb)) == BUTTON_NORMAL)
  526.         return;
  527.     /* don't scroll further on line mode */
  528.     if(state > BUTTON_DOWNLINEHI)
  529.         WindowScroll(screen, ButtonRegion(sb));
  530.     sb->buttonset = BUTTON_NORMAL;
  531.     DrawButton(sb);
  532.     screen->timeout = NULL;
  533.     XUngrabMouse();
  534. }
  535.  
  536. WindowScroll(screen, top)
  537.     register Screen *screen;
  538.     int top;
  539. {
  540.     register int i, lines;
  541.     register int scrolltop, scrollheight, refreshtop;
  542.  
  543.     if((i = screen->topline - top) == 0)
  544.         return;
  545.     if(screen->cursor_state)
  546.         HideCursor();
  547.     lines = i > 0 ? i : -i;
  548.     if(lines > screen->max_row + 1)
  549.         lines = screen->max_row + 1;
  550.     scrollheight = screen->max_row - lines + 1;
  551.     if(i > 0)
  552.         refreshtop = scrolltop = 0;
  553.     else {
  554.         scrolltop = lines;
  555.         refreshtop = scrollheight;
  556.     }
  557.     if(scrollheight > 0) {
  558.         if (screen->multiscroll && scrollheight == 1 &&
  559.          screen->topline == 0 && screen->top_marg == 0 &&
  560.          screen->bot_marg == screen->max_row) {
  561.             if (screen->incopy < 0 && screen->scrolls == 0)
  562.                 CopyWait (screen);
  563.             screen->scrolls++;
  564.         } else {
  565.             if (screen->incopy)
  566.                 CopyWait (screen);
  567.             screen->incopy = -1;
  568.         }
  569.         XMoveArea(VWindow(screen), screen->border, scrolltop *
  570.          FontHeight(screen) + screen->border + Titlebar(screen),
  571.          screen->border, (scrolltop + i) * FontHeight(screen) +
  572.          screen->border + Titlebar(screen), Width(screen),
  573.          scrollheight * FontHeight(screen));
  574.     }
  575.     screen->topline = top;
  576.     XTileSet(VWindow(screen), screen->border, refreshtop * FontHeight(screen) +
  577.      screen->border + Titlebar(screen), Width(screen), lines *
  578.      FontHeight(screen), screen->bgndtile);
  579.     ScrnRefresh(screen, refreshtop, 0, lines, screen->max_col + 1);
  580. }
  581.  
  582. ScrollBarOn(screen, show, init)
  583.     register Screen *screen;
  584.     int show, init;
  585. {
  586.     register int border = 2 * screen->border;
  587.     register int i;
  588.     char *realloc(), *calloc();
  589.  
  590.     if(screen->scrollbar)
  591.         return;
  592.     if(!screen->sb) {
  593.         if((screen->sb = CreateScrollBar(VWindow(screen),
  594.          Width(screen) + border, Titlebar(screen) - 1,
  595.          Height(screen) + border, screen->foreground,
  596.          screen->background, screen->bordertile, 0,
  597.          screen->max_row + 1, 0, 0, screen->arrow)) == NULL) {
  598.             Bell();
  599.             return;
  600.         }
  601.         if((screen->allbuf = (ScrnBuf) realloc(screen->buf,
  602.          2*(screen->max_row + 2 + screen->savelines) * sizeof(char *)))
  603.          == NULL)
  604.             Error (ERROR_SBRALLOC);
  605.         screen->buf = &screen->allbuf[2 * screen->savelines];
  606.         bcopy ((char *)screen->allbuf, (char *)screen->buf,
  607.          2 * (screen->max_row + 2) * sizeof (char *));
  608.         for(i = 2 * screen->savelines - 1 ; i >= 0 ; i--)
  609.             if((screen->allbuf[i] =
  610.              calloc(screen->max_col + 1, sizeof(char))) == NULL)
  611.                 Error (ERROR_SBRALLOC2);
  612.         screen->sb->saveset = !screen->alternate;
  613.     } else {
  614.         XConfigureWindow(screen->sb->bar, FullWidth(screen),
  615.          Titlebar(screen) - 1, (SCROLLBARWIDTH - 1),
  616.          i = FullHeight(screen) - Titlebar(screen));
  617.         screen->sb->set.height = i - BARSTART;
  618.         screen->sb->set.regionheight = screen->max_row + 1;
  619.     }
  620.     if(show) {
  621.         screen->scrollbar = SCROLLBARWIDTH;
  622.         ShowScrollBar(screen->sb);
  623.         if(!init) {
  624.             XSetResizeHint(VWindow(screen), border + SCROLLBARWIDTH,
  625.              border + Titlebar(screen) + screen->statusheight,
  626.              FontWidth(screen), FontHeight(screen));
  627.             XChangeWindow(VWindow(screen), (screen->max_col + 1) *
  628.              FontWidth(screen) + border + SCROLLBARWIDTH,
  629.              FontHeight(screen) * (screen->max_row + 1) +
  630.              screen->statusheight + border + Titlebar(screen));
  631.         }
  632.     }
  633. }
  634.  
  635. ScrollBarOff(screen)
  636.     register Screen *screen;
  637. {
  638.     register int border = 2 * screen->border;
  639.  
  640.     if(!screen->scrollbar)
  641.         return;
  642.     screen->sb->action = HIDE;
  643.     screen->scrollbar = 0;
  644.     XSetResizeHint(VWindow(screen), border, border + Titlebar(screen) +
  645.      screen->statusheight, FontWidth(screen), FontHeight(screen));
  646.     XChangeWindow(VWindow(screen), (screen->max_col + 1) * FontWidth(screen) +
  647.      border, FontHeight(screen) * (screen->max_row + 1) + screen->statusheight
  648.      + border + Titlebar(screen));
  649. }
  650.  
  651. ClearLinesOffTop(screen)
  652.     register Screen *screen;
  653. {
  654.     if(!screen->sb)
  655.         return;
  656.     if(screen->topline)
  657.         WindowScroll(screen, 0);
  658.     SetScrollBarTop(screen->sb, 0);
  659.     DrawScrollRegion(screen->sb);
  660. }
  661.  
  662. SetSaveState(sb, state)
  663.     register ScrollBar *sb;
  664.     int state;
  665. {
  666.     extern Terminal term;
  667.     register Screen *screen = &term.screen;
  668.  
  669.     if(screen->alternate)
  670.         return;
  671.     if(screen->scroll_amt)
  672.         FlushScroll(screen);
  673.     sb->saveset = state;
  674.     DrawSave(sb);
  675. }
  676.  
  677. SetButtonState(sb, state)
  678.     register ScrollBar *sb;
  679.     int state;
  680. {
  681.     sb->buttonset = state;
  682.     DrawButton(sb);
  683. }
  684.  
  685. static Window
  686. Make_tiled_window(bitmap_width, bitmap_height, bitmap_bits, foreground,
  687.  background, bgnd, parent, x, y, width, height, borderwidth, bordertile)
  688.     int bitmap_width, bitmap_height, foreground, background, x, y, width,
  689.      height, borderwidth;
  690.     short *bitmap_bits;
  691.     Window parent;
  692.     Pixmap *bgnd, bordertile;
  693. {
  694.     register Pixmap pix;
  695.     register Window w;
  696.     extern Pixmap Make_tile();
  697.  
  698.     if((pix = Make_tile(bitmap_width, bitmap_height, bitmap_bits,
  699.      foreground, background)) == NULL)
  700.         return(NULL);
  701.     w = XCreateWindow(parent, x, y, width, height, borderwidth, bordertile,
  702.      pix);
  703.     *bgnd = pix;
  704.     return(w);
  705. }
  706.  
  707. Pixmap
  708. Make_tile(bitmap_width, bitmap_height, bitmap_bits, foreground, background)
  709.     int bitmap_width, bitmap_height, foreground, background;
  710.     short *bitmap_bits;
  711. {
  712.     register Bitmap bm;
  713.     register Pixmap pix;
  714.  
  715.     if((bm = XStoreBitmap(bitmap_width, bitmap_height, bitmap_bits))
  716.      == NULL)
  717.         return(NULL);
  718.     pix = XMakePixmap(bm, foreground, background);
  719.     XFreeBitmap(bm);
  720.     return(pix);
  721. }
  722.  
  723. ScrollToBottom(sb)
  724. register ScrollBar *sb;
  725. {
  726.     SetScrollBarValue(sb, GetScrollBarBottom(sb));
  727.     DrawScrollRegion(sb);
  728.     WindowScroll(&term.screen, GetScrollBarValue(sb));
  729. }
  730.  
  731. #ifdef MODEMENU
  732. #define    SMENU_SCROLLKEY    0
  733. #define    SMENU_SCROLLINPUT (SMENU_SCROLLKEY+1)
  734. #define    SMENU_LINESTOP    (SMENU_SCROLLINPUT+1)
  735. #define    SMENU_LINE    (SMENU_LINESTOP+1)
  736. #define    SMENU_CLEARTOP    (SMENU_LINE+1)
  737. #define    SMENU_HIDE    (SMENU_CLEARTOP+1)
  738.  
  739. static char *stext[] = {
  740.     "Scroll to Bottom on Key",
  741.     "Scroll to Bottom on Input",
  742.     "Lines Off Top Saved",
  743.     "-",
  744.     "Clear Lines Off Top",
  745.     "Hide Scrollbar",
  746.     0,
  747. };
  748.  
  749.  
  750. static int salternate;
  751. static int slinestop;
  752. static int sscrollinput;
  753. static int sscrollkey;
  754.  
  755. Menu *ssetupmenu(menu)
  756. register Menu **menu;
  757. {
  758.     register Screen *screen = &term.screen;
  759.     register char **cp;
  760.  
  761.     if (*menu == NULL) {
  762.         if ((*menu = NewMenu("Scrollbar", re_verse)) == NULL)
  763.             return(NULL);
  764.         for(cp = stext ; *cp ; cp++)
  765.             AddMenuItem(*menu, *cp);
  766.         if(sscrollkey = screen->scrollkey)
  767.             CheckItem(*menu, SMENU_SCROLLKEY);
  768.         if(sscrollinput = screen->scrollinput)
  769.             CheckItem(*menu, SMENU_SCROLLINPUT);
  770.         if(slinestop = (screen->sb && GetSaveState(screen->sb)))
  771.             CheckItem(*menu, SMENU_LINESTOP);
  772.         if(salternate = screen->alternate)
  773.             DisableItem(*menu, SMENU_LINESTOP);
  774.         DisableItem(*menu, SMENU_LINE);
  775.         return(*menu);
  776.     }
  777.     if(sscrollkey != screen->scrollkey)
  778.         SetItemCheck(*menu, SMENU_SCROLLKEY, (sscrollkey =
  779.          screen->scrollkey));
  780.     if(sscrollinput != screen->scrollinput)
  781.         SetItemCheck(*menu, SMENU_SCROLLINPUT, (sscrollinput =
  782.          screen->scrollinput));
  783.     if(screen->sb && slinestop != GetSaveState(screen->sb))
  784.         SetItemCheck(*menu, SMENU_LINESTOP, (slinestop =
  785.          GetSaveState(screen->sb)));
  786.     if(salternate != screen->alternate)
  787.         SetItemDisable(*menu, SMENU_LINESTOP, (salternate =
  788.          screen->alternate));
  789.     return(*menu);
  790. }
  791.  
  792. sdomenufunc(item)
  793. int item;
  794. {
  795.     register Screen *screen = &term.screen;
  796.  
  797.     switch (item) {
  798.      case SMENU_SCROLLKEY:
  799.         screen->scrollkey = !screen->scrollkey;
  800.         break;
  801.  
  802.      case SMENU_SCROLLINPUT:
  803.         screen->scrollinput = !screen->scrollinput;
  804.         break;
  805.  
  806.      case SMENU_LINESTOP:
  807.         SetSaveState(screen->sb, !GetSaveState(screen->sb));
  808.         break;
  809.  
  810.      case SMENU_CLEARTOP:
  811.         ClearLinesOffTop(screen);
  812.         break;
  813.  
  814.      case SMENU_HIDE:
  815.         ScrollBarOff(screen);
  816.         break;
  817.     }
  818. }
  819. #endif MODEMENU
  820. RAZZLE!DAZZLE
  821. fi    # End scrollbar.c
  822. if test -f tabs.c
  823. then
  824.     echo shar: will not overwrite existing file "'tabs.c'"
  825. else
  826. echo 'x - tabs.c'
  827. cat << \RAZZLE!DAZZLE > tabs.c
  828. /*
  829.  *    $Source: /u1/X/xterm/RCS/tabs.c,v $
  830.  *    $Header: tabs.c,v 10.100 86/12/01 14:45:38 jg Rel $
  831.  */
  832.  
  833. #ifndef lint
  834. static char *rcsid_tabs_c = "$Header: tabs.c,v 10.100 86/12/01 14:45:38 jg Rel $";
  835. #endif    lint
  836.  
  837. #include <X/mit-copyright.h>
  838.  
  839. /* Copyright    Massachusetts Institute of Technology    1984    */
  840.  
  841. /* tabs.c */
  842.  
  843. #ifndef lint
  844. /* @(#)tabs.c       X10/6.6B 12/26/86 */
  845. #endif    lint
  846.  
  847. #include <X/Xlib.h>
  848. #include "scrollbar.h"
  849. #include "ptyx.h"
  850. /*
  851.  * This file presumes 32bits/word.  This is somewhat of a crock, and should
  852.  * be fixed sometime.
  853.  */
  854.  
  855. /*
  856.  * places tabstops at only every 8 columns
  857.  */
  858. TabReset(tabs)
  859. Tabs    tabs;
  860. {
  861.     register int i;
  862.  
  863.     for (i=0; i<TAB_ARRAY_SIZE; ++i)
  864.         tabs[i] = 0;
  865.  
  866.     for (i=0; i<MAX_TABS; i+=8)
  867.         TabSet(tabs, i);
  868. }    
  869.  
  870.  
  871. /*
  872.  * places a tabstop at col
  873.  */
  874. TabSet(tabs, col)
  875. Tabs    tabs;
  876. {
  877.     tabs[col >> 5] |= (1 << (col & 31));
  878. }
  879.  
  880. /*
  881.  * clears a tabstop at col
  882.  */
  883. TabClear(tabs, col)
  884. Tabs    tabs;
  885. {
  886.     tabs[col >> 5] &= ~(1 << (col & 31));
  887. }
  888.  
  889. /*
  890.  * returns the column of the next tabstop
  891.  * (or MAX_TABS - 1 if there are no more).
  892.  * A tabstop at col is ignored.
  893.  */
  894. TabNext (tabs, col)
  895. Tabs    tabs;
  896. {
  897.     extern Terminal term;
  898.     register Screen *screen = &term.screen;
  899.  
  900.     if(screen->curses && screen->do_wrap && (term.flags & WRAPAROUND)) {
  901.         Index(screen, 1);
  902.         col = screen->cur_col = screen->do_wrap = 0;
  903.     }
  904.     for (++col; col<MAX_TABS; ++col)
  905.         if (tabs[col >> 5] & (1 << (col & 31)))
  906.             return (col);
  907.  
  908.     return (MAX_TABS - 1);
  909. }
  910.  
  911. /*
  912.  * clears all tabs
  913.  */
  914. TabZonk (tabs)
  915. Tabs    tabs;
  916. {
  917.     register int i;
  918.  
  919.     for (i=0; i<TAB_ARRAY_SIZE; ++i)
  920.         tabs[i] = 0;
  921. }
  922. RAZZLE!DAZZLE
  923. fi    # End tabs.c
  924. if test -f termcap
  925. then
  926.     echo shar: will not overwrite existing file "'termcap'"
  927. else
  928. echo 'x - termcap'
  929. cat << \RAZZLE!DAZZLE > termcap
  930. # @(#)termcap       X10/6.6B 12/26/86
  931. vs|xterm|vs100|xterm terminal emulator (X window system):\
  932.     :cr=^M:do=^J:nl=^J:bl=^G:le=^H:ho=\E[H:\
  933.     :co#80:li#65:cl=\E[H\E[2J:bs:am:cm=\E[%i%d;%dH:nd=\E[C:up=\E[A:\
  934.     :ce=\E[K:cd=\E[J:so=\E[7m:se=\E[m:us=\E[4m:ue=\E[m:\
  935.     :md=\E[1m:mr=\E[7m:me=\E[m:\
  936.     :ku=\EOA:kd=\EOB:kr=\EOC:kl=\EOD:kb=^H:\
  937.     :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:ta=^I:pt:sf=\n:sr=\EM:\
  938.     :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:\
  939.     :MT:ks=\E[?1h\E=:ke=\E[?1l\E>:\
  940.     :is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l:\
  941.     :rs=\E[r\E<\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l:xn:\
  942.     :AL=\E[%dL:DL=\E[%dM:IC=\E[%d@:DC=\E[%dP:\
  943.     :ti=\E7\E[?47h:te=\E[2J\E[?47l\E8:\
  944.     :hs:ts=\E[?E\E[?%i%dT:fs=\E[?F:es:ds=\E[?E:
  945. v2|xterms|vs100s|xterm terminal emulator (small)(X window system):\
  946.     :co#80:li#24:tc=xterm:
  947. RAZZLE!DAZZLE
  948. fi    # End termcap
  949. if test -f terminfo
  950. then
  951.     echo shar: will not overwrite existing file "'terminfo'"
  952. else
  953. echo 'x - terminfo'
  954. cat << \RAZZLE!DAZZLE > terminfo
  955. # @(#)terminfo       X10/6.6B 12/26/86
  956. xterm|vs100|xterm terminal emulator,
  957.     ind=^J, cols#80, lines#65,
  958.     clear=\E[H\E[2J, cub1=^H, am, cup=\E[%i%p1%d;%p2%dH,
  959.     cuf1=\E[C, cuu1=\E[A, el=\E[K, ed=\E[J,
  960.     cud=\E[%p1%dB, cuu=\E[%p1%dA, cub=\E[%p1%dD,
  961.     cuf=\E[%p1%dC, km,
  962.     smso=\E[7m, rmso=\E[m, smul@, rmul@,
  963.     bold=\E[1m, rev=\E[7m, blink=@, sgr0=\E[m,
  964.     rs1=\E>\E[1;3;4;5;6l\E[?7h\E[m\E[r\E[2J\E[H, rs2=@
  965.     kf1=\EOP, kf2=\EOQ, kf3=\EOR, kf4=\EOS, ht=^I, ri=\EM,
  966.     vt@, xon@, csr=\E[%i%p1%d;%p2%dr,
  967.     il=\E[%p1%dL, dl=\E[%p1%dM, il1=\E[L, dl1=\E[M,
  968.     ich=\E[%p1%d@, dch=\E[%p1%dP, ich1=\E[@, dch1=\E[P,
  969.     use=vt100-am,
  970. xterms|vs100s|xterm terminal emulator (small screen 24x80),
  971.     cols#80, lines#24,
  972.     use=xterm,
  973. RAZZLE!DAZZLE
  974. fi    # End terminfo
  975. if test -f util.c
  976. then
  977.     echo shar: will not overwrite existing file "'util.c'"
  978. else
  979. echo 'x - util.c'
  980. cat << \RAZZLE!DAZZLE > util.c
  981. /*
  982.  *    $Source: /u1/X/xterm/RCS/util.c,v $
  983.  *    $Header: util.c,v 10.100 86/12/01 14:45:43 jg Rel $
  984.  */
  985.  
  986. #include <X/mit-copyright.h>
  987.  
  988. /* Copyright    Massachusetts Institute of Technology    1984, 1985    */
  989.  
  990. /* util.c */
  991.  
  992. #ifndef lint
  993. static char sccs_id[] = "@(#)util.c\tX10/6.6B\t12/26/86";
  994. #endif    lint
  995.  
  996. #include <stdio.h>
  997. #include <X/Xlib.h>
  998. #include <signal.h>
  999. #include <setjmp.h>
  1000. typedef int *jmp_ptr;
  1001.  
  1002. #include "scrollbar.h"
  1003. #include "ptyx.h"
  1004. #include "data.h"
  1005. #include "error.h"
  1006.  
  1007. /*
  1008.  * These routines are used for the jump scroll feature
  1009.  */
  1010. FlushScroll(screen)
  1011. register Screen *screen;
  1012. {
  1013.     register int i;
  1014.     register int shift = -screen->topline;
  1015.     register int bot = screen->max_row - shift;
  1016.     register int refreshtop;
  1017.     register int refreshheight;
  1018.     register int scrolltop;
  1019.     register int scrollheight;
  1020.  
  1021.     if(screen->cursor_state)
  1022.         HideCursor();
  1023.     if(screen->scroll_amt > 0) {
  1024.         refreshheight = screen->refresh_amt;
  1025.         scrollheight = screen->bot_marg - screen->top_marg -
  1026.          refreshheight + 1;
  1027.         if((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
  1028.          (i = screen->max_row - screen->scroll_amt + 1))
  1029.             refreshtop = i;
  1030.         if(screen->sb && GetSaveState(screen->sb) &&
  1031.          screen->top_marg == 0) {
  1032.             scrolltop = 0;
  1033.             if((scrollheight += shift) > i)
  1034.                 scrollheight = i;
  1035.             if((i = screen->bot_marg - bot) > 0 &&
  1036.              (refreshheight -= i) < screen->scroll_amt)
  1037.                 refreshheight = screen->scroll_amt;
  1038.             if((i = -GetScrollBarTop(screen->sb)) <
  1039.              screen->savelines) {
  1040.                 if((i += screen->scroll_amt) >
  1041.                  screen->savelines)
  1042.                     i = screen->savelines;
  1043.                 SetScrollBarTop(screen->sb, -i);
  1044.                 DrawScrollRegion(screen->sb);
  1045.             }
  1046.         } else {
  1047.             scrolltop = screen->top_marg + shift;
  1048.             if((i = bot - (screen->bot_marg - screen->refresh_amt +
  1049.              screen->scroll_amt)) > 0) {
  1050.                 if(bot < screen->bot_marg)
  1051.                     refreshheight = screen->scroll_amt + i;
  1052.             } else {
  1053.                 scrollheight += i;
  1054.                 refreshheight = screen->scroll_amt;
  1055.                 if((i = screen->top_marg + screen->scroll_amt -
  1056.                  1 - bot) > 0) {
  1057.                     refreshtop += i;
  1058.                     refreshheight -= i;
  1059.                 }
  1060.             }
  1061.         }
  1062.     } else {
  1063.         refreshheight = -screen->refresh_amt;
  1064.         scrollheight = screen->bot_marg - screen->top_marg -
  1065.          refreshheight + 1;
  1066.         refreshtop = screen->top_marg + shift;
  1067.         scrolltop = refreshtop + refreshheight;
  1068.         if((i = screen->bot_marg - bot) > 0)
  1069.             scrollheight -= i;
  1070.         if((i = screen->top_marg + refreshheight - 1 - bot) > 0)
  1071.             refreshheight -= i;
  1072.     }
  1073.     if(scrollheight > 0) {
  1074.         if (screen->multiscroll && scrollheight == 1 &&
  1075.          screen->topline == 0 && screen->top_marg == 0 &&
  1076.          screen->bot_marg == screen->max_row) {
  1077.             if (screen->incopy < 0 && screen->scrolls == 0)
  1078.                 CopyWait (screen);
  1079.             screen->scrolls++;
  1080.         } else {
  1081.             if (screen->incopy)
  1082.                 CopyWait (screen);
  1083.             screen->incopy = -1;
  1084.         }
  1085.  
  1086.         XMoveArea (VWindow(screen), screen->border, (scrolltop +
  1087.          screen->scroll_amt) * FontHeight(screen) + screen->border +
  1088.          Titlebar(screen), screen->border, scrolltop * FontHeight(screen)
  1089.          + screen->border + Titlebar(screen), Width(screen),
  1090.          scrollheight * FontHeight(screen));
  1091.     }
  1092.     screen->scroll_amt = 0;
  1093.     screen->refresh_amt = 0;
  1094.     if(refreshheight > 0) {
  1095.         XTileSet (VWindow(screen), screen->border, refreshtop *
  1096.          FontHeight(screen) + screen->border + Titlebar(screen),
  1097.          Width(screen), refreshheight * FontHeight(screen),
  1098.          screen->bgndtile);
  1099.         ScrnRefresh(screen, refreshtop, 0, refreshheight,
  1100.          screen->max_col + 1);
  1101.     }
  1102. }
  1103.  
  1104. AddToRefresh(screen)
  1105. register Screen *screen;
  1106. {
  1107.     register int amount = screen->refresh_amt;
  1108.     register int row = screen->cur_row;
  1109.  
  1110.     if(amount == 0 || screen->instatus)
  1111.         return(0);
  1112.     if(amount > 0) {
  1113.         register int bottom;
  1114.  
  1115.         if(row == (bottom = screen->bot_marg) - amount) {
  1116.             screen->refresh_amt++;
  1117.             return(1);
  1118.         }
  1119.         return(row >= bottom - amount + 1 && row <= bottom);
  1120.     } else {
  1121.         register int top;
  1122.  
  1123.         amount = -amount;
  1124.         if(row == (top = screen->top_marg) + amount) {
  1125.             screen->refresh_amt--;
  1126.             return(1);
  1127.         }
  1128.         return(row <= top + amount - 1 && row >= top);
  1129.     }
  1130. }
  1131.  
  1132. /* 
  1133.  * scrolls the screen by amount lines, erases bottom, doesn't alter 
  1134.  * cursor position (i.e. cursor moves down amount relative to text).
  1135.  * All done within the scrolling region, of course. 
  1136.  * requires: amount > 0
  1137.  */
  1138. Scroll (screen, amount)
  1139. register Screen *screen;
  1140. register int amount;
  1141. {
  1142.     register int i = screen->bot_marg - screen->top_marg + 1;
  1143.     register int shift;
  1144.     register int bot;
  1145.     register int refreshtop;
  1146.     register int refreshheight;
  1147.     register int scrolltop;
  1148.     register int scrollheight;
  1149.  
  1150.     if(screen->cursor_state)
  1151.         HideCursor();
  1152.     if (amount > i)
  1153.         amount = i;
  1154.     if(screen->jumpscroll) {
  1155.     if(screen->scroll_amt > 0) {
  1156.         if(screen->refresh_amt + amount > i)
  1157.             FlushScroll(screen);
  1158.         screen->scroll_amt += amount;
  1159.         screen->refresh_amt += amount;
  1160.     } else {
  1161.         if(screen->scroll_amt < 0)
  1162.             FlushScroll(screen);
  1163.         screen->scroll_amt = amount;
  1164.         screen->refresh_amt = amount;
  1165.     }
  1166.     refreshheight = 0;
  1167.     } else {
  1168.  
  1169.     if (amount == i) {
  1170.         ClearScreen(screen);
  1171.         return;
  1172.     }
  1173.     shift = -screen->topline;
  1174.     bot = screen->max_row - shift;
  1175.     scrollheight = i - amount;
  1176.     refreshheight = amount;
  1177.     if((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
  1178.      (i = screen->max_row - refreshheight + 1))
  1179.         refreshtop = i;
  1180.     if(screen->sb && GetSaveState(screen->sb) && screen->top_marg == 0) {
  1181.         scrolltop = 0;
  1182.         if((scrollheight += shift) > i)
  1183.             scrollheight = i;
  1184.         if((i = -GetScrollBarTop(screen->sb)) < screen->savelines) {
  1185.             if((i += amount) > screen->savelines)
  1186.                 i = screen->savelines;
  1187.             SetScrollBarTop(screen->sb, -i);
  1188.             DrawScrollRegion(screen->sb);
  1189.         }
  1190.     } else {
  1191.         scrolltop = screen->top_marg + shift;
  1192.         if((i = screen->bot_marg - bot) > 0) {
  1193.             scrollheight -= i;
  1194.             if((i = screen->top_marg + amount - 1 - bot) >= 0) {
  1195.                 refreshtop += i;
  1196.                 refreshheight -= i;
  1197.             }
  1198.         }
  1199.     }
  1200.     if(scrollheight > 0) {
  1201.         if (screen->multiscroll
  1202.         && amount==1 && screen->topline == 0
  1203.         && screen->top_marg==0
  1204.         && screen->bot_marg==screen->max_row) {
  1205.             if (screen->incopy<0 && screen->scrolls==0)
  1206.                 CopyWait(screen);
  1207.             screen->scrolls++;
  1208.         } else {
  1209.             if (screen->incopy)
  1210.                 CopyWait(screen);
  1211.             screen->incopy = -1;
  1212.         }
  1213.  
  1214.         XMoveArea(VWindow(screen), screen->border, (scrolltop+amount) *
  1215.          FontHeight(screen) + screen->border + Titlebar(screen),
  1216.          screen->border, scrolltop * FontHeight(screen) + screen->border
  1217.          + Titlebar(screen), Width(screen), scrollheight *
  1218.          FontHeight(screen));
  1219.     }
  1220.     if(refreshheight > 0) {
  1221.         XTileSet (VWindow(screen), screen->border, refreshtop *
  1222.          FontHeight(screen) + screen->border + Titlebar(screen),
  1223.          Width(screen), refreshheight * FontHeight(screen),
  1224.          screen->bgndtile);
  1225.         if(refreshheight > shift)
  1226.             refreshheight = shift;
  1227.     }
  1228.     }
  1229.     if(screen->sb && GetSaveState(screen->sb) && screen->top_marg == 0)
  1230.         ScrnDeleteLine(screen->allbuf, screen->bot_marg +
  1231.          screen->savelines, 0, amount, screen->max_col + 1);
  1232.     else
  1233.         ScrnDeleteLine(screen->buf, screen->bot_marg, screen->top_marg,
  1234.          amount, screen->max_col + 1);
  1235.     if(refreshheight > 0)
  1236.         ScrnRefresh(screen, refreshtop, 0, refreshheight,
  1237.          screen->max_col + 1);
  1238. }
  1239.  
  1240.  
  1241. /*
  1242.  * Reverse scrolls the screen by amount lines, erases top, doesn't alter
  1243.  * cursor position (i.e. cursor moves up amount relative to text).
  1244.  * All done within the scrolling region, of course.
  1245.  * Requires: amount > 0
  1246.  */
  1247. RevScroll(screen, amount)
  1248. register Screen *screen;
  1249. register int amount;
  1250. {
  1251.     register int i = screen->bot_marg - screen->top_marg + 1;
  1252.     register int shift;
  1253.     register int bot;
  1254.     register int refreshtop;
  1255.     register int refreshheight;
  1256.     register int scrolltop;
  1257.     register int scrollheight;
  1258.  
  1259.     if(screen->cursor_state)
  1260.         HideCursor();
  1261.     if (amount > i)
  1262.         amount = i;
  1263.     if(screen->jumpscroll) {
  1264.     if(screen->scroll_amt < 0) {
  1265.         if(-screen->refresh_amt + amount > i)
  1266.             FlushScroll(screen);
  1267.         screen->scroll_amt -= amount;
  1268.         screen->refresh_amt -= amount;
  1269.     } else {
  1270.         if(screen->scroll_amt > 0)
  1271.             FlushScroll(screen);
  1272.         screen->scroll_amt = -amount;
  1273.         screen->refresh_amt = -amount;
  1274.     }
  1275.     } else {
  1276.     shift = -screen->topline;
  1277.     bot = screen->max_row - shift;
  1278.     refreshheight = amount;
  1279.     scrollheight = screen->bot_marg - screen->top_marg -
  1280.      refreshheight + 1;
  1281.     refreshtop = screen->top_marg + shift;
  1282.     scrolltop = refreshtop + refreshheight;
  1283.     if((i = screen->bot_marg - bot) > 0)
  1284.         scrollheight -= i;
  1285.     if((i = screen->top_marg + refreshheight - 1 - bot) > 0)
  1286.         refreshheight -= i;
  1287.     if(scrollheight > 0) {
  1288.         if (screen->multiscroll
  1289.         && amount==1 && screen->topline == 0
  1290.         && screen->top_marg==0
  1291.         && screen->bot_marg==screen->max_row) {
  1292.             if (screen->incopy<0 && screen->scrolls==0)
  1293.                 CopyWait(screen);
  1294.             screen->scrolls++;
  1295.         } else {
  1296.             if (screen->incopy)
  1297.                 CopyWait(screen);
  1298.             screen->incopy = -1;
  1299.         }
  1300.  
  1301.         XMoveArea (VWindow(screen), screen->border, (scrolltop-amount) *
  1302.          FontHeight(screen) + screen->border + Titlebar(screen),
  1303.          screen->border, scrolltop * FontHeight(screen) + screen->border
  1304.          + Titlebar(screen), Width(screen), scrollheight *
  1305.          FontHeight(screen));
  1306.     }
  1307.     if(refreshheight > 0)
  1308.         XTileSet (VWindow(screen), screen->border, refreshtop *
  1309.          FontHeight(screen) + screen->border + Titlebar(screen),
  1310.          Width(screen), refreshheight * FontHeight(screen),
  1311.          screen->bgndtile);
  1312.     }
  1313.     ScrnInsertLine (screen->buf, screen->bot_marg, screen->top_marg,
  1314.             amount, screen->max_col + 1);
  1315. }
  1316.  
  1317. /*
  1318.  * If cursor not in scrolling region, returns.  Else,
  1319.  * inserts n blank lines at the cursor's position.  Lines above the
  1320.  * bottom margin are lost.
  1321.  */
  1322. InsertLine (screen, n)
  1323. register Screen *screen;
  1324. register int n;
  1325. {
  1326.     register int i;
  1327.     register int shift;
  1328.     register int bot;
  1329.     register int refreshtop;
  1330.     register int refreshheight;
  1331.     register int scrolltop;
  1332.     register int scrollheight;
  1333.  
  1334.     if (screen->cur_row < screen->top_marg ||
  1335.      screen->cur_row > screen->bot_marg)
  1336.         return;
  1337.     if(screen->cursor_state)
  1338.         HideCursor();
  1339.     screen->do_wrap = 0;
  1340.     if (n > (i = screen->bot_marg - screen->cur_row + 1))
  1341.         n = i;
  1342.     if(screen->jumpscroll) {
  1343.     if(screen->scroll_amt <= 0 &&
  1344.      screen->cur_row <= -screen->refresh_amt) {
  1345.         if(-screen->refresh_amt + n > screen->max_row + 1)
  1346.             FlushScroll(screen);
  1347.         screen->scroll_amt -= n;
  1348.         screen->refresh_amt -= n;
  1349.     } else if(screen->scroll_amt)
  1350.         FlushScroll(screen);
  1351.     }
  1352.     if(!screen->scroll_amt) {
  1353.     shift = -screen->topline;
  1354.     bot = screen->max_row - shift;
  1355.     refreshheight = n;
  1356.     scrollheight = screen->bot_marg - screen->cur_row - refreshheight + 1;
  1357.     refreshtop = screen->cur_row + shift;
  1358.     scrolltop = refreshtop + refreshheight;
  1359.     if((i = screen->bot_marg - bot) > 0)
  1360.         scrollheight -= i;
  1361.     if((i = screen->cur_row + refreshheight - 1 - bot) > 0)
  1362.         refreshheight -= i;
  1363.     if(scrollheight > 0) {
  1364.         if (screen->incopy)
  1365.             CopyWait (screen);
  1366.         screen->incopy = -1;
  1367.         XMoveArea (VWindow(screen), screen->border, (scrolltop - n) *
  1368.          FontHeight(screen) + screen->border + Titlebar(screen),
  1369.          screen->border, scrolltop * FontHeight(screen) + screen->border
  1370.          + Titlebar(screen), Width(screen), scrollheight *
  1371.          FontHeight(screen));
  1372.     }
  1373.     if(refreshheight > 0)
  1374.         XTileSet (VWindow(screen),
  1375.          screen->border, refreshtop * FontHeight(screen) + screen->border
  1376.          + Titlebar(screen), Width(screen), refreshheight *
  1377.          FontHeight(screen), screen->bgndtile);
  1378.     }
  1379.     /* adjust screen->buf */
  1380.     ScrnInsertLine(screen->buf, screen->bot_marg, screen->cur_row, n,
  1381.             screen->max_col + 1);
  1382. }
  1383.  
  1384. /*
  1385.  * If cursor not in scrolling region, returns.  Else, deletes n lines
  1386.  * at the cursor's position, lines added at bottom margin are blank.
  1387.  */
  1388. DeleteLine(screen, n)
  1389. register Screen *screen;
  1390. register int n;
  1391. {
  1392.     register int i;
  1393.     register int shift;
  1394.     register int bot;
  1395.     register int refreshtop;
  1396.     register int refreshheight;
  1397.     register int scrolltop;
  1398.     register int scrollheight;
  1399.  
  1400.     if (screen->cur_row < screen->top_marg ||
  1401.      screen->cur_row > screen->bot_marg)
  1402.         return;
  1403.     if(screen->cursor_state)
  1404.         HideCursor();
  1405.     screen->do_wrap = 0;
  1406.     if (n > (i = screen->bot_marg - screen->cur_row + 1))
  1407.         n = i;
  1408.     if(screen->jumpscroll) {
  1409.     if(screen->scroll_amt >= 0 && screen->cur_row == screen->top_marg) {
  1410.         if(screen->refresh_amt + n > screen->max_row + 1)
  1411.             FlushScroll(screen);
  1412.         screen->scroll_amt += n;
  1413.         screen->refresh_amt += n;
  1414.     } else if(screen->scroll_amt)
  1415.         FlushScroll(screen);
  1416.     }
  1417.     if(!screen->scroll_amt) {
  1418.  
  1419.     shift = -screen->topline;
  1420.     bot = screen->max_row - shift;
  1421.     scrollheight = i - n;
  1422.     refreshheight = n;
  1423.     if((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
  1424.      (i = screen->max_row - refreshheight + 1))
  1425.         refreshtop = i;
  1426.     if(screen->sb && GetSaveState(screen->sb) && screen->cur_row == 0) {
  1427.         scrolltop = 0;
  1428.         if((scrollheight += shift) > i)
  1429.             scrollheight = i;
  1430.         if((i = -GetScrollBarTop(screen->sb)) < screen->savelines) {
  1431.             if((i += n) > screen->savelines)
  1432.                 i = screen->savelines;
  1433.             SetScrollBarTop(screen->sb, -i);
  1434.             DrawScrollRegion(screen->sb);
  1435.         }
  1436.     } else {
  1437.         scrolltop = screen->cur_row + shift;
  1438.         if((i = screen->bot_marg - bot) > 0) {
  1439.             scrollheight -= i;
  1440.             if((i = screen->cur_row + n - 1 - bot) >= 0) {
  1441.                 refreshheight -= i;
  1442.             }
  1443.         }
  1444.     }
  1445.     if(scrollheight > 0) {
  1446.         if (screen->incopy)
  1447.             CopyWait(screen);
  1448.         screen->incopy = -1;
  1449.  
  1450.         XMoveArea (VWindow(screen), screen->border, (scrolltop + n) *
  1451.          FontHeight(screen) + screen->border + Titlebar(screen),
  1452.          screen->border, scrolltop * FontHeight(screen) + screen->border
  1453.          + Titlebar(screen), Width(screen), scrollheight *
  1454.          FontHeight(screen));
  1455.     }
  1456.     if(refreshheight > 0)
  1457.         XTileSet (VWindow(screen), screen->border, refreshtop *
  1458.          FontHeight(screen) + screen->border + Titlebar(screen),
  1459.          Width(screen), refreshheight * FontHeight(screen),
  1460.          screen->bgndtile);
  1461.     }
  1462.     /* adjust screen->buf */
  1463.     if(screen->sb && GetSaveState(screen->sb) && screen->cur_row == 0)
  1464.         ScrnDeleteLine(screen->allbuf, screen->bot_marg +
  1465.          screen->savelines, 0, n, screen->max_col + 1);
  1466.     else
  1467.         ScrnDeleteLine(screen->buf, screen->bot_marg, screen->cur_row,
  1468.          n, screen->max_col + 1);
  1469. }
  1470.  
  1471. /*
  1472.  * Insert n blanks at the cursor's position, no wraparound
  1473.  */
  1474. InsertChar (screen, n)
  1475. register Screen *screen;
  1476. register int n;
  1477. {
  1478.     register int width = n * FontWidth(screen), cx, cy;
  1479.  
  1480.     if(screen->cursor_state)
  1481.         HideCursor();
  1482.     screen->do_wrap = 0;
  1483.     if(screen->cur_row - screen->topline <= screen->max_row ||
  1484.      screen->instatus) {
  1485.         if(!AddToRefresh(screen)) {
  1486.         if(screen->scroll_amt)
  1487.             FlushScroll(screen);
  1488.     
  1489.         if (screen->incopy)
  1490.             CopyWait (screen);
  1491.         screen->incopy = -1;
  1492.     
  1493.         cx = CursorX (screen, screen->cur_col);
  1494.         cy = CursorY (screen, screen->cur_row);
  1495.         XMoveArea(VWindow(screen), cx, cy, cx + width, cy,
  1496.              Width(screen) - (screen->cur_col + n) * FontWidth(screen),
  1497.              FontHeight(screen));
  1498.         XPixSet(VWindow(screen), cx, cy,
  1499.              width, FontHeight(screen), screen->instatus ?
  1500.              screen->foreground : screen->background);
  1501.     
  1502.         }
  1503.     }
  1504.     /* adjust screen->buf */
  1505.     ScrnInsertChar(screen->buf, screen->cur_row, screen->cur_col, n,
  1506.             screen->max_col + 1);
  1507. }
  1508.  
  1509. /*
  1510.  * Deletes n chars at the cursor's position, no wraparound.
  1511.  */
  1512. DeleteChar (screen, n)
  1513. register Screen *screen;
  1514. register int    n;
  1515. {
  1516.     register int width, cx, cy;
  1517.  
  1518.     if(screen->cursor_state)
  1519.         HideCursor();
  1520.     screen->do_wrap = 0;
  1521.     if (n > (width = screen->max_col + 1 - screen->cur_col))
  1522.           n = width;
  1523.         
  1524.     if(screen->cur_row - screen->topline <= screen->max_row ||
  1525.      screen->instatus) {
  1526.         if(!AddToRefresh(screen)) {
  1527.         if(screen->scroll_amt)
  1528.             FlushScroll(screen);
  1529.     
  1530.         width = n * FontWidth(screen);
  1531.     
  1532.         if (screen->incopy)
  1533.             CopyWait (screen);
  1534.         screen->incopy = -1;
  1535.     
  1536.         cx = CursorX (screen, screen->cur_col);
  1537.         cy = CursorY (screen, screen->cur_row);
  1538.         XMoveArea(VWindow(screen), cx + width, cy, cx, cy,
  1539.              Width(screen) - (screen->cur_col + n) * FontWidth(screen),
  1540.              FontHeight(screen));
  1541.         XPixSet (VWindow(screen),
  1542.              screen->border + Width(screen) - width, cy,
  1543.              width, FontHeight(screen), screen->instatus ?
  1544.              screen->foreground : screen->background);
  1545.     
  1546.         }
  1547.     }
  1548.     /* adjust screen->buf */
  1549.     ScrnDeleteChar (screen->buf, screen->cur_row, screen->cur_col, n,
  1550.             screen->max_col + 1);
  1551.  
  1552. }
  1553.  
  1554. /*
  1555.  * Clear from cursor position to beginning of display, inclusive.
  1556.  */
  1557. ClearAbove (screen)
  1558. register Screen *screen;
  1559. {
  1560.     register top, height;
  1561.  
  1562.     if(screen->cursor_state)
  1563.         HideCursor();
  1564.     if((top = -screen->topline) <= screen->max_row) {
  1565.         if(screen->scroll_amt)
  1566.             FlushScroll(screen);
  1567.         if((height = screen->cur_row + top) > screen->max_row)
  1568.             height = screen->max_row;
  1569.         if((height -= top) > 0)
  1570.             XTileSet(VWindow(screen), screen->border, top *
  1571.              FontHeight(screen) + screen->border + Titlebar(screen),
  1572.              Width(screen), height * FontHeight(screen),
  1573.              screen->bgndtile);
  1574.  
  1575.         if(screen->cur_row - screen->topline <= screen->max_row)
  1576.             ClearLeft(screen);
  1577.     }
  1578.     ClearBufRows(screen, 0, screen->cur_row - 1);
  1579. }
  1580.  
  1581. /*
  1582.  * Clear from cursor position to end of display, inclusive.
  1583.  */
  1584. ClearBelow (screen)
  1585. register Screen *screen;
  1586. {
  1587.     register top;
  1588.  
  1589.     ClearRight(screen);
  1590.     if((top = screen->cur_row - screen->topline) <= screen->max_row) {
  1591.         if(screen->scroll_amt)
  1592.             FlushScroll(screen);
  1593.         if(++top <= screen->max_row)
  1594.             XTileSet(VWindow(screen), screen->border, top *
  1595.              FontHeight(screen) + screen->border + Titlebar(screen),
  1596.              Width(screen), (screen->max_row - top + 1) *
  1597.              FontHeight(screen), screen->bgndtile);
  1598.     }
  1599.     ClearBufRows(screen, screen->cur_row + 1, screen->max_row);
  1600. }
  1601.  
  1602. /* 
  1603.  * Clear last part of cursor's line, inclusive.
  1604.  */
  1605. ClearRight (screen)
  1606. register Screen *screen;
  1607. {
  1608.     if(screen->cursor_state)
  1609.         HideCursor();
  1610.     screen->do_wrap = 0;
  1611.     if(screen->cur_row - screen->topline <= screen->max_row ||
  1612.      screen->instatus) {
  1613.         if(!AddToRefresh(screen)) {
  1614.         if(screen->scroll_amt)
  1615.             FlushScroll(screen);
  1616.         XPixSet(VWindow(screen),
  1617.          CursorX(screen, screen->cur_col),
  1618.          CursorY(screen, screen->cur_row),
  1619.          Width(screen) - screen->cur_col * FontWidth(screen),
  1620.          FontHeight(screen), screen->instatus ? screen->foreground :
  1621.          screen->background);
  1622.         }
  1623.     }
  1624.     bzero(screen->buf [2 * screen->cur_row] + screen->cur_col,
  1625.            (screen->max_col - screen->cur_col + 1));
  1626.     bzero(screen->buf [2 * screen->cur_row + 1] + screen->cur_col,
  1627.            (screen->max_col - screen->cur_col + 1));
  1628. }
  1629.  
  1630. /*
  1631.  * Clear first part of cursor's line, inclusive.
  1632.  */
  1633. ClearLeft (screen)
  1634. register Screen *screen;
  1635. {
  1636.     if(screen->cursor_state)
  1637.         HideCursor();
  1638.     screen->do_wrap = 0;
  1639.     if(screen->cur_row - screen->topline <= screen->max_row ||
  1640.      screen->instatus) {
  1641.         if(!AddToRefresh(screen)) {
  1642.         if(screen->scroll_amt)
  1643.             FlushScroll(screen);
  1644.     
  1645.         XPixSet (VWindow(screen),
  1646.              screen->border, CursorY (screen, screen->cur_row),
  1647.              (screen->cur_col + 1) * FontWidth(screen),
  1648.              FontHeight(screen), screen->instatus ? screen->foreground :
  1649.              screen->background);
  1650.         }
  1651.     }
  1652.     bzero (screen->buf [2 * screen->cur_row], (screen->cur_col + 1));
  1653.     bzero (screen->buf [2 * screen->cur_row + 1], (screen->cur_col + 1));
  1654. }
  1655.  
  1656. /* 
  1657.  * Erase the cursor's line.
  1658.  */
  1659. ClearLine(screen)
  1660. register Screen *screen;
  1661. {
  1662.     if(screen->cursor_state)
  1663.         HideCursor();
  1664.     screen->do_wrap = 0;
  1665.     if(screen->cur_row - screen->topline <= screen->max_row ||
  1666.      screen->instatus) {
  1667.         if(!AddToRefresh(screen)) {
  1668.         if(screen->scroll_amt)
  1669.             FlushScroll(screen);
  1670.         XPixSet (VWindow(screen),
  1671.              screen->border, CursorY (screen, screen->cur_row),
  1672.              Width(screen), FontHeight(screen), screen->instatus ?
  1673.              screen->foreground : screen->background);
  1674.         }
  1675.     }
  1676.     bzero (screen->buf [2 * screen->cur_row], (screen->max_col + 1));
  1677.     bzero (screen->buf [2 * screen->cur_row + 1], (screen->max_col + 1));
  1678. }
  1679.  
  1680. ClearScreen(screen)
  1681. register Screen *screen;
  1682. {
  1683.     register int top;
  1684.  
  1685.     if(screen->cursor_state)
  1686.         HideCursor();
  1687.     screen->do_wrap = 0;
  1688.     if((top = -screen->topline) <= screen->max_row) {
  1689.         if(screen->scroll_amt)
  1690.             FlushScroll(screen);
  1691.         if(top == 0 && !screen->statusline)
  1692.             XClear(VWindow(screen));
  1693.         else
  1694.             XTileSet(VWindow(screen), screen->border, top *
  1695.              FontHeight(screen) + screen->border + Titlebar(screen),
  1696.              Width(screen), (screen->max_row - top + 1) *
  1697.              FontHeight(screen), screen->bgndtile);
  1698.     }
  1699.     ClearBufRows (screen, 0, screen->max_row);
  1700.     screen->pagecnt = 0;
  1701. }
  1702.  
  1703. CopyWait(screen)
  1704. register Screen *screen;
  1705. {
  1706.     XEvent reply;
  1707.     XEvent *rep = &reply;
  1708.  
  1709.     while (1) {
  1710.         XWindowEvent (VWindow(screen), ExposeRegion|ExposeCopy, &reply);
  1711.         switch (reply.type) {
  1712.         case ExposeRegion:
  1713.             if (((XExposeEvent *)rep)->detail == ExposeCopy &&
  1714.                 screen->incopy <= 0) {
  1715.                 screen->incopy = 1;
  1716.                 if (screen->scrolls > 0)
  1717.                     screen->scrolls--;
  1718.             }
  1719.             HandleExposure (screen, &reply);
  1720.             break;
  1721.         case ExposeCopy:
  1722.             if (screen->incopy <= 0 && screen->scrolls > 0)
  1723.                 screen->scrolls--;
  1724.             if (screen->scrolls == 0) {
  1725.                 screen->incopy = 0;
  1726.                 return;
  1727.             }
  1728.             screen->incopy = -1;
  1729.             break;
  1730.         }
  1731.     }
  1732. }
  1733. /*
  1734.  * This routine handles exposure events
  1735.  */
  1736. HandleExposure (screen, reply)
  1737. register Screen *screen;
  1738. register XExposeEvent *reply;
  1739. {
  1740.     register int toprow, leftcol, nrows, ncols;
  1741.     extern Terminal term;    /* kludge */
  1742.     XExposeRegionEvent event;
  1743.  
  1744.     if((toprow = (reply->y - screen->border - Titlebar(screen)) /
  1745.      FontHeight(screen)) < 0)
  1746.         toprow = 0;
  1747.     if((leftcol = (reply->x - screen->border) / FontWidth(screen)) < 0)
  1748.         leftcol = 0;
  1749.     nrows = (reply->y + reply->height - 1 - screen->border
  1750.      - Titlebar(screen)) / FontHeight(screen) - toprow + 1;
  1751.     ncols = (reply->x + reply->width - 1 - screen->border) /
  1752.             FontWidth(screen) - leftcol + 1;
  1753.     toprow -= screen->scrolls;
  1754.     if (toprow < 0) {
  1755.         nrows += toprow;
  1756.         toprow = 0;
  1757.     }
  1758.     if (toprow + nrows - 1 > screen->max_row)
  1759.         nrows = screen->max_row - toprow + 1 + screen->statusline;
  1760.     if (leftcol + ncols - 1 > screen->max_col)
  1761.         ncols = screen->max_col - leftcol + 1;
  1762.  
  1763.     if (nrows > 0 && ncols > 0) {
  1764.         ScrnRefresh (screen, toprow, leftcol, nrows, ncols);
  1765.         if (screen->cur_row >= toprow &&
  1766.             screen->cur_row < toprow + nrows &&
  1767.             screen->cur_col >= leftcol &&
  1768.             screen->cur_col < leftcol + ncols)
  1769.             return (1);
  1770.     }
  1771.     return (0);
  1772. }
  1773.  
  1774. ReverseVideo (term)
  1775.     Terminal *term;
  1776. {
  1777.     register Screen *screen = &term->screen;
  1778.     register Pixmap pix;
  1779.     register int tmp;
  1780.     register Window tek = TWindow(screen);
  1781.     extern Pixmap B_Pixmap;
  1782.     extern Pixmap W_Pixmap;
  1783.  
  1784.     if(screen->color & C_BACKGROUND)
  1785.         XFreePixmap(screen->bgndtile);
  1786.     tmp = screen->background;
  1787.     if(screen->cursorcolor == screen->foreground)
  1788.         screen->cursorcolor = tmp;
  1789.     if(screen->mousecolor == screen->foreground)
  1790.         screen->mousecolor = tmp;
  1791.     screen->background = screen->foreground;
  1792.     screen->foreground = tmp;
  1793.  
  1794.     screen->color = (screen->color & ~C_FBMASK) | switchfb[screen->color
  1795.      & C_FBMASK];
  1796.  
  1797.     if(screen->color & C_BACKGROUND) {
  1798.         if(!(screen->bgndtile = XMakeTile(screen->background)))
  1799.             Error(ERROR_UBACK);
  1800.     } else
  1801.         screen->bgndtile = (screen->background == W_Pixel) ? W_Pixmap
  1802.          : B_Pixmap;
  1803.  
  1804.     XFreeCursor(screen->curs);
  1805.     screen->curs = make_xterm(screen->mousecolor, screen->background,
  1806.      GXcopy);
  1807.     XFreeCursor(screen->arrow);
  1808.     screen->arrow = make_arrow(screen->mousecolor, screen->background,
  1809.      GXcopy);
  1810.  
  1811.     XDefineCursor(VWindow(screen), screen->curs);
  1812.     if(screen->sb)
  1813.         XDefineCursor(screen->sb->bar, screen->sb->cursor =
  1814.          screen->arrow);
  1815.     if(screen->title.tbar)
  1816.         XDefineCursor(screen->title.tbar, screen->arrow);
  1817.     if(tek)
  1818.         XDefineCursor(tek, screen->arrow);
  1819. #ifdef MODEMENU
  1820.     MenuNewCursor(screen->arrow);
  1821. #endif MODEMENU
  1822.  
  1823.     if (screen->background < 2 && screen->foreground < 2) {
  1824.         if (screen->bgndtile == B_Pixmap)
  1825.         screen->bordertile = W_Pixmap;
  1826.         else if (screen->bgndtile == W_Pixmap)
  1827.         screen->bordertile = B_Pixmap;
  1828.         pix = screen->bordertile;
  1829.         if(screen->sb)
  1830.         XChangeBorder (screen->sb->bar, pix);
  1831.         if(screen->title.tbar)
  1832.         XChangeBorder (screen->title.tbar, pix);
  1833.         if(tek && screen->Ttitle.tbar)
  1834.         XChangeBorder (screen->Ttitle.tbar, pix);
  1835.         if(screen->borderwidth > 0) {
  1836.         XChangeBorder (VWindow(screen), pix);
  1837.         XChangeBorder (screen->iconVwin.window, pix);
  1838.         if(tek) {
  1839.             XChangeBorder (tek, pix);
  1840.             XChangeBorder (screen->iconTwin.window, pix);
  1841.         }
  1842.         }
  1843.     }
  1844.  
  1845.     XChangeBackground (VWindow(screen), screen->bgndtile);
  1846.     XChangeBackground (screen->iconVwin.window, screen->bgndtile);
  1847.     if(screen->title.tbar)
  1848.         XChangeBackground (screen->title.tbar, screen->bgndtile);
  1849.     if(tek) {
  1850.         XChangeBackground (screen->iconTwin.window, screen->bgndtile);
  1851.         if(screen->Ttitle.tbar)
  1852.         XChangeBackground (screen->Ttitle.tbar, screen->bgndtile);
  1853.         TekReverseVideo(screen);
  1854.     }
  1855.     XClear (VWindow(screen));
  1856.     XClear (screen->iconVwin.window);
  1857.     ScrnRefresh (screen, 0, 0, screen->max_row + 1 + screen->statusline,
  1858.      screen->max_col + 1);
  1859.     if(screen->Tshow) {
  1860.         XClear (tek);
  1861.         XClear (screen->iconTwin.window);
  1862.         TekExpose((XExposeWindowEvent *)0);
  1863.     }
  1864.     if(Titlebar(screen)) {
  1865.         XClear(screen->title.tbar);
  1866.         VTTitleExpose(NULL);
  1867.         if(screen->Tshow) {
  1868.         XClear(screen->Ttitle.tbar);
  1869.         TekTitleExpose(NULL);
  1870.         }
  1871.     }
  1872. }
  1873. RAZZLE!DAZZLE
  1874. fi    # End util.c
  1875. if test ! -d Xlib
  1876. then
  1877.     mkdir Xlib
  1878. fi
  1879. if test -f Xlib/Makefile
  1880. then
  1881.     echo shar: will not overwrite existing file "'Xlib/Makefile'"
  1882. else
  1883. echo 'x - Xlib/Makefile'
  1884. cat << \RAZZLE!DAZZLE > Xlib/Makefile
  1885. INCLUDES= -I/usr/include/X -I../../Xlib
  1886. C2= /lib/c2
  1887. #
  1888. # The KEYBD define may be include to include the keyboard mods.
  1889. CFLAGS= -O ${INCLUDES} ${NETOPTIONS} -DKEYBD
  1890.  
  1891. .SUFFIXES: .o .h .c
  1892.  
  1893. .c.o:
  1894. #    ${CC} -pg ${CFLAGS} -c -S $*.c
  1895. #    ${C2} $*.s | ../../inline/inline | ${AS} -o $*.o
  1896. #    rm -f $*.s
  1897. #    -ld -X -r $*.o
  1898. #    mv a.out profiled/$*.o
  1899.     ${CC} ${CFLAGS} -c -S $*.c
  1900.     ${C2} $*.s | ../../inline/inline | ${AS} -o $*.o
  1901.     rm -f $*.s
  1902.     -ld -x -r $*.o
  1903.     mv a.out $*.o
  1904.  
  1905. OLIST=    XKeyBind.o
  1906.  
  1907. libX.a: $(OLIST)
  1908.     ar cr libX.a $(OLIST)
  1909.     @ranlib libX.a
  1910. #
  1911. #libX_p.a: $(OLIST)
  1912. #    cd profiled; ar cr ../libX_p.a $(OLIST)
  1913. #    @ranlib libX_p.a
  1914.  
  1915. $(OLIST): ../../Xlib/Xlib.h
  1916.  
  1917. XKeyBind.o: ../../Xlib/Xkeyboard.h ../../Xlib/Xkeymap.h Xdefault.h
  1918.  
  1919. XGetDefault.o: Xdefault.h
  1920. RAZZLE!DAZZLE
  1921. fi    # End Xlib/Makefile
  1922. if test -f Xlib/README
  1923. then
  1924.     echo shar: will not overwrite existing file "'Xlib/README'"
  1925. else
  1926. echo 'x - Xlib/README'
  1927. cat << \RAZZLE!DAZZLE > Xlib/README
  1928. This directory contains a changes to the Xlib routines XKeyBind.c:
  1929.  
  1930. XKeyBind.c:    This will allow (in the future) to define keymaps with
  1931.         the environment variable KEYBD.  This is needed, for example,
  1932.         when I log into a Sun from some other workstation.  Then, on
  1933.         the Sun, I wish to pop a window back on my workstation.  Since
  1934.         the default keymap would be for the Sun, if I were on some
  1935.         other workstation, my keyboard would be messed up.  I could
  1936.         keep a .Xkeymap file on the Sun, but if I use different
  1937.         workstations to log in, sometimes it might work and other times
  1938.         it wouldn't.  If I were originally on a MicroVax and set
  1939.         my KEYBD environment variable (from the .login file) to
  1940.         mvaxII, for instance, then I would get the right keymap.  From
  1941.         another Sun, I might set KEYBD to sun3.  The names of these
  1942.         keymap files have not yet been established yet.
  1943. RAZZLE!DAZZLE
  1944. fi    # End Xlib/README
  1945. if test -f Xlib/XKeyBind.c
  1946. then
  1947.     echo shar: will not overwrite existing file "'Xlib/XKeyBind.c'"
  1948. else
  1949. echo 'x - Xlib/XKeyBind.c'
  1950. cat << \RAZZLE!DAZZLE > Xlib/XKeyBind.c
  1951. #include <X/mit-copyright.h>
  1952.  
  1953. /* $Header: XKeyBind.c,v 10.12 86/07/21 15:27:14 wesommer Rel $ */
  1954. /* Copyright 1985, Massachusetts Institute of Technology */
  1955.  
  1956. #include "XlibInternal.h"
  1957. #include <sys/file.h>
  1958. #include <sys/stat.h>
  1959. #include "Xkeymap.h"
  1960. #include "Xkeyboard.h"
  1961. #include <stdio.h>
  1962. #include <strings.h>
  1963. #ifdef KEYBD
  1964. #include "Xdefault.h"
  1965. #endif KEYBD
  1966.  
  1967. #define EMPTY_ENTRY LeftMask 
  1968.    /* if the "metabits" field of a runtime table entry contains this,
  1969.     it's an empty entry */
  1970.  
  1971. static KeyMapElt *keymap = NULL;
  1972. static Bool inited = FALSE;
  1973.  
  1974. static ExtensionHeader *ext_begin, *ext_end;
  1975.  
  1976. /* Runtime table: contains multiple-byte character bindings defined
  1977.   at runtime with XRebindCode */
  1978.  
  1979. typedef struct {
  1980.     unsigned char keycode;
  1981.     unsigned short metabits;
  1982.     short length;
  1983.     char *value;
  1984.     } RuntimeTableEntry;
  1985.  
  1986. static RuntimeTableEntry
  1987.    *rt_begin,  /* first entry of runtime table */
  1988.    *rt_end,    /* this and all succeeding entries are empty */
  1989.    *rt_buf_end;/* points beyond end of allocated storage for table */
  1990.  
  1991. #ifdef KEYBD
  1992. char *keyboardtype = NULL;
  1993. #endif KEYBD
  1994.  
  1995. #define RT_INITIAL_SIZE 100  /* initial size of runtime table */
  1996. #define RT_INCREMENT 40  /* size to grow by if expanded */
  1997.  
  1998. XUseKeymap(filename) 
  1999.     char *filename;
  2000. {
  2001.     int file = -1;
  2002.     int filesize;
  2003.     unsigned char magic;
  2004.     struct stat filestat;
  2005.     file = open (filename, O_RDONLY, 0);
  2006.     if (file < 0) {
  2007.         return(0);        /* no keymap file found */
  2008.     }
  2009.     fstat (file, &filestat);
  2010.     filesize = filestat.st_size - 1; /* first byte is magic number */
  2011.     if (filesize < 256*sizeof(KeyMapElt)) {
  2012.     fprintf (stderr, "Keymap file %s is too small\n", filename);
  2013.     close (file);
  2014.     return(0);
  2015.     }
  2016.     read (file, &magic, 1);
  2017.     if (magic != X_KEYMAP_MAGIC) {
  2018.     fprintf (stderr, 
  2019.       "Keymap file %s doesn't begin with the proper magic number\n",
  2020.       filename);
  2021.         close (file);
  2022.           return(0);
  2023.     }
  2024.     keymap = (KeyMapElt *) malloc (filesize);
  2025.     if (!keymap) {
  2026.     close (file);
  2027.           return(0);  /* couldn't malloc; just act like there isn't a keymap */
  2028.     }
  2029.     read (file, (char *) keymap, filesize);
  2030.     ext_begin = (ExtensionHeader *) (keymap + 256);
  2031.     ext_end = (ExtensionHeader *) (((char *) keymap) + filesize);
  2032.     rt_begin = (RuntimeTableEntry *) malloc (RT_INITIAL_SIZE*sizeof(RuntimeTableEntry));
  2033.     if (!rt_begin)
  2034.          _XIOError (_XlibCurrentDisplay);
  2035.     rt_end = rt_begin;
  2036.     rt_buf_end = rt_begin + RT_INITIAL_SIZE;
  2037.     close (file);
  2038.     inited = TRUE;
  2039.     return(1);
  2040. }
  2041.  
  2042. static Initialize() {
  2043.     int file = -1;
  2044.     int filesize;
  2045.     unsigned char magic;
  2046.     struct stat filestat;
  2047.     char *getenv();
  2048.     char *filename = NULL;
  2049. #ifdef KEYBD
  2050.     char *home;
  2051.     char *kdefault = "default";
  2052.     char *keybddir = KEYBDDIR;
  2053. #else KEYBD
  2054.     char *home = getenv ("HOME");
  2055. #endif KEYBD
  2056.  
  2057.     inited = TRUE;
  2058. #ifdef KEYBD
  2059.     if(keyboardtype && *keyboardtype) {    /* Use keyboard type keymap */
  2060.     filename = malloc(strlen(keybddir) + strlen(keyboardtype) + 1);
  2061.     strcpy(filename, keybddir);
  2062.     strcat(filename, keyboardtype);
  2063.     if((file = open (filename, O_RDONLY, 0)) < 0) {
  2064.         free (filename);
  2065.         filename = NULL;
  2066.     }
  2067.     }
  2068.     if(file < 0 && (home = getenv ("HOME")))
  2069. #else KEYBD
  2070.     if (home)
  2071. #endif KEYBD
  2072.      {
  2073.     int homelen = strlen (home);
  2074.     char *keymapstr = "/.Xkeymap";
  2075.     int keymapstrlen = strlen (keymapstr);
  2076.     filename = malloc (homelen + keymapstrlen + 1);
  2077.     strncpy (filename, home, homelen+1);
  2078.     strncat (filename, keymapstr, keymapstrlen);
  2079.     file = open (filename, O_RDONLY, 0);
  2080.     }
  2081. #ifdef KEYBD
  2082.     if (file < 0) {    /* Try system default keymap */
  2083.     if(filename)
  2084.         free(filename);
  2085.     filename = malloc(strlen(keybddir) + strlen(kdefault) + 1);
  2086.     strcpy(filename, keybddir);
  2087.     strcat(filename, kdefault);
  2088.     file = open (filename, O_RDONLY, 0);
  2089.     }
  2090. #endif KEYBD
  2091.     if (file < 0) {
  2092.     if(filename)
  2093.         free(filename);
  2094.     return; /* no keymap file found */
  2095.     }
  2096.     fstat (file, &filestat);
  2097.     filesize = filestat.st_size - 1; /* first byte is magic number */
  2098.     if (filesize < 256*sizeof(KeyMapElt)) {
  2099.     fprintf (stderr, "Keymap file %s is too small\n", filename);
  2100.     close (file);
  2101.     free (filename);
  2102.     return;
  2103.     }
  2104.     read (file, &magic, 1);
  2105.     if (magic != X_KEYMAP_MAGIC) {
  2106.     fprintf (stderr, 
  2107.       "Keymap file %s doesn't begin with the proper magic number\n",
  2108.       filename);
  2109.         close (file);
  2110.     free (filename);
  2111.           return;
  2112.     }
  2113.     keymap = (KeyMapElt *) malloc (filesize);
  2114.     if (!keymap) {
  2115.     close (file);
  2116.     free (filename);
  2117.           return;  /* couldn't malloc; just act like there isn't a keymap */
  2118.     }
  2119.     read (file, (char *) keymap, filesize);
  2120.     ext_begin = (ExtensionHeader *) (keymap + 256);
  2121.     ext_end = (ExtensionHeader *) (((char *) keymap) + filesize);
  2122.     rt_begin = (RuntimeTableEntry *) malloc (RT_INITIAL_SIZE*sizeof(RuntimeTableEntry));
  2123.     if (!rt_begin)
  2124.          _XIOError (_XlibCurrentDisplay);
  2125.     rt_end = rt_begin;
  2126.     rt_buf_end = rt_begin + RT_INITIAL_SIZE;
  2127.     free (filename);
  2128.     close (file);
  2129.     }
  2130.  
  2131. /* this routine is used when initialization failed to find a
  2132.    valid keymap file */
  2133. static char *BackstopLookupMapping (event, nbytes)
  2134.     XKeyPressedEvent *event;
  2135.     int *nbytes;
  2136.     {
  2137.     int detail = event->detail;
  2138.     register int keycode = detail & ValueMask;
  2139.     extern KeyMapEntry StdMap[];
  2140.     static char c;
  2141.     short s;  /* needed to distinguish a real character (e.g. \0377) from -1 */
  2142.     s = StdMap [keycode] [KeyState(detail)];
  2143.     c = s;
  2144.     if ((detail & ShiftLockMask) && (c >= 'a') && (c <= 'z'))
  2145.         c += ('A' - 'a');
  2146.     if (IsTypewriterKey(keycode)
  2147.       || keycode == KC_ESC || keycode == KC_BS || keycode == KC_LF)
  2148.     *nbytes = (s == -1 ? 0 : 1);
  2149.     else
  2150.         *nbytes = 0;
  2151.     return (&c);
  2152.     }
  2153.  
  2154. char *XLookupMapping (event, nbytes)
  2155.     XKeyPressedEvent *event;
  2156.     int *nbytes;
  2157.     {
  2158.     int detail = event->detail;
  2159.     unsigned int metabits = FullKeyState (detail);
  2160.     unsigned int key = detail & ValueMask;
  2161.     register unsigned char *the_char;
  2162.  
  2163.     if (!inited)
  2164.           Initialize();
  2165.     if (!keymap)
  2166.         return (BackstopLookupMapping (event, nbytes));
  2167.  
  2168.     the_char = &keymap [key] [metabits];
  2169.  
  2170.     switch (*the_char) {
  2171.  
  2172.           case UNBOUND: {
  2173.         *nbytes = 0;
  2174.         return (NULL);
  2175.         }
  2176.  
  2177.           case EXTENSION_BOUND: {
  2178.         register ExtensionHeader *this;
  2179.         for (this = ext_begin; this < ext_end; NextExtension(this))
  2180.             if ((key == this->keycode)
  2181.             && ((metabits == this->metabits) || (this->metabits == DontCareMetaBits))) {
  2182.                 *nbytes = this->length;
  2183.                 return ((char *)this + ExtensionHeaderSize);
  2184.                 }
  2185.         /* if we get here, no match was found in the table extension */
  2186.         *nbytes = 0;
  2187.         return (NULL);
  2188.         }
  2189.  
  2190.         case RUNTIME_TABLE_BOUND: {
  2191.         register RuntimeTableEntry *entry;
  2192.         for (entry = rt_begin; entry < rt_end; entry++)
  2193.             if ((key == entry->keycode)
  2194.             && ((metabits == entry->metabits) || (entry->metabits == DontCareMetaBits))) {
  2195.             *nbytes = entry->length;
  2196.             return (entry->value);
  2197.             }
  2198.  
  2199.         /* if we get here, no match was found in the runtime table */
  2200.         *nbytes = 0;
  2201.         return (NULL);
  2202.         }
  2203.  
  2204.     default: {
  2205.         *nbytes = 1;
  2206.         return ((char *)the_char);
  2207.         }
  2208.           }
  2209.  
  2210.     }
  2211.  
  2212.  
  2213. XRebindCode (keycode, metabits, str, nbytes)
  2214.     unsigned int keycode, metabits;
  2215.     char *str;
  2216.     int nbytes;
  2217.     {
  2218.     unsigned char *table_char;
  2219.     metabits = FullKeyState (metabits);  /* shift meta bits to rightmost four bits */
  2220.     if (!inited)
  2221.         Initialize();
  2222.     if (!keymap)
  2223.         return;  /* no keymap file; what else can I do? */
  2224.     table_char = &keymap [keycode] [metabits];
  2225.     if (nbytes == 0) {
  2226.     if (*table_char == RUNTIME_TABLE_BOUND)
  2227.         Unbind (keycode, metabits);
  2228.     *table_char = UNBOUND;
  2229.     return;
  2230.     }
  2231.     if ((nbytes == 1) && SingleCharBound (*str)) {
  2232.         if (*table_char == RUNTIME_TABLE_BOUND)
  2233.         Unbind (keycode, metabits);
  2234.     *table_char = *str;
  2235.     return;
  2236.     }
  2237.     
  2238.     /* the new binding is either multi-character, or one of the
  2239.        three reserved special characters */
  2240.  
  2241.     if (*table_char == RUNTIME_TABLE_BOUND) {
  2242.     /* entry is already in table; just change its binding */
  2243.     register RuntimeTableEntry *entry;
  2244.     for (entry = rt_begin; entry < rt_end; entry++)
  2245.         if (keycode == entry->keycode && metabits == entry->metabits) {
  2246.         entry->value = str;
  2247.         entry->length = nbytes;
  2248.         return;
  2249.         }
  2250.     /* if we get here, entry wasn't found in table; shouldn't
  2251.      * ever happen!  Not much to do but fall through to 
  2252.      * the following code.  */
  2253.         }
  2254.  
  2255.     /* new binding must go in a new entry in the table */
  2256.     *table_char = RUNTIME_TABLE_BOUND;
  2257.     if (rt_end < rt_buf_end) {
  2258.     rt_end->keycode = keycode;
  2259.     rt_end->metabits = metabits;
  2260.     rt_end->value = str;
  2261.     rt_end++->length = nbytes;
  2262.     return;
  2263.     }
  2264.  
  2265.     /* no room at end of table; look for holes in middle */
  2266.     {
  2267.     register RuntimeTableEntry *entry;
  2268.     for (entry = rt_begin; entry < rt_end; entry++)
  2269.         if (entry->metabits == EMPTY_ENTRY) {
  2270.         entry->keycode = keycode;
  2271.         entry->metabits = metabits;
  2272.         entry->value = str;
  2273.         entry->length = nbytes;
  2274.         return;
  2275.         }
  2276.     }
  2277.  
  2278.     /* no room in table at all.  Must expand it. */
  2279.     {
  2280.     int rt_length = rt_end - rt_begin;
  2281.     rt_begin = (RuntimeTableEntry *) realloc ((char *)rt_begin, (rt_length+RT_INCREMENT)*sizeof (RuntimeTableEntry));
  2282.     rt_end = rt_begin + rt_length;
  2283.     rt_buf_end = rt_end + RT_INCREMENT;
  2284.     rt_end->keycode = keycode;
  2285.     rt_end->metabits = metabits;
  2286.     rt_end->value = str;
  2287.     rt_end++->length = nbytes;
  2288.     }
  2289.     }
  2290.     
  2291.  
  2292. static Unbind (keycode, metabits)
  2293.     unsigned int keycode, metabits;
  2294.     {
  2295.     register RuntimeTableEntry *entry;
  2296.     for (entry = rt_begin; entry < rt_end; entry++)
  2297.         if (keycode == entry->keycode && metabits == entry->metabits) {
  2298.         entry->metabits = EMPTY_ENTRY;
  2299.         return;
  2300.         }
  2301.     }
  2302. RAZZLE!DAZZLE
  2303. fi    # End Xlib/XKeyBind.c
  2304. echo '***** End of' xterm 6.6B - Part 7 of 7 '*****'
  2305. exit
  2306.